/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.nfe;

import br.com.modelo.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import util.JPAUtil;
import util.JSFUtil;

/**
 *
 * @author gilberto.costa
 */
public class DadosNfeController {

    public DadosNfeController() {
    }

    public void atualizaTotais(NfeCabecalho nfeDetalhe) {
        // TODO : Os cálculos abaixo estão corretos?

//        NfeCabecalho nfeCabecalho = (NfeCabecalhoVO) telaNfeDetalhe.getFormDadosNfe().getVOModel().getValueObject();
        if (nfeDetalhe.getBaseCalculoIcms() != null) {
            nfeDetalhe.setBaseCalculoIcms(nfeDetalhe.getBaseCalculoIcms().add(nfeDetalhe.getBaseCalculoIcms()));
        }
        if (nfeDetalhe.getValorIcms() != null) {
            nfeDetalhe.setValorIcms(nfeDetalhe.getValorIcms().add(nfeDetalhe.getValorIcms()));
        }
        if (nfeDetalhe.getValorTotal() != null) {
            nfeDetalhe.setValorTotalProdutos(nfeDetalhe.getValorTotalProdutos().add(nfeDetalhe.getValorTotal()));
        }
        if (nfeDetalhe.getBaseCalculoIcmsSt() != null) {
            nfeDetalhe.setBaseCalculoIcmsSt(nfeDetalhe.getBaseCalculoIcmsSt().add(nfeDetalhe.getBaseCalculoIcmsSt()));
        }
        if (nfeDetalhe.getValorIcmsSt() != null) {
            nfeDetalhe.setValorIcmsSt(nfeDetalhe.getValorIcmsSt().add(nfeDetalhe.getValorIcmsSt()));
        }
        if (nfeDetalhe.getValorDesconto() != null) {
            nfeDetalhe.setValorDesconto(nfeDetalhe.getValorDesconto().add(nfeDetalhe.getValorDesconto()));
        }
        if (nfeDetalhe.getValorPis() != null) {
            nfeDetalhe.setValorPis(nfeDetalhe.getValorPis().add(nfeDetalhe.getValorPis()));
        }
        if (nfeDetalhe.getValorCofins() != null) {
            nfeDetalhe.setValorCofins(nfeDetalhe.getValorCofins().add(nfeDetalhe.getValorCofins()));
        }

        nfeDetalhe.setValorTotal(nfeDetalhe.getValorTotalProdutos().add(nfeDetalhe.getValorIcmsSt()).add(nfeDetalhe.getValorPis()).add(nfeDetalhe.getValorCofins()).add(nfeDetalhe.getValorDespesasAcessorias()).subtract(nfeDetalhe.getValorDesconto()));

    }

    private void valoresPadrao() {
//        NfeCabecalho nfeCabecalho = (NfeCabecalhoVO) telaNfeDetalhe.getFormDadosNfe().getVOModel().getValueObject();
        NfeCabecalho nfeCabecalho = new NfeCabecalho();

//        Integer numero = new NumeroNfeController().loadData();
        Integer numero = 1;
        DecimalFormat formatoNumero = new DecimalFormat("000000000");
        DecimalFormat formatoCodigoNumerico = new DecimalFormat("00000000");
        SimpleDateFormat formatoHora = new SimpleDateFormat("HH:mm:ss");

        // TODO : Onde armazenar os parâmetros diversos?
        // TODO : Quais valores padrões devemos carregar e de onde devemos buscá-los?
        nfeCabecalho.setAmbiente('2');
        nfeCabecalho.setVersaoProcessoEmissao(100);
        nfeCabecalho.setTipoEmissao('1');
        nfeCabecalho.setCodigoMunicipio(5300108);
        nfeCabecalho.setFinalidadeEmissao('1');
        nfeCabecalho.setNumero(formatoNumero.format(numero));
        nfeCabecalho.setCodigoNumerico(formatoCodigoNumerico.format(numero));
        nfeCabecalho.setCodigoModelo("55");
        nfeCabecalho.setSerie("000");
//        nfeCabecalho.setStatusNota('0');
        nfeCabecalho.setTipoOperacao('1');
        nfeCabecalho.setNaturezaOperacao("Venda de Mercadoria");
        Date dataAtual = new Date();
        nfeCabecalho.setDataEmissao(dataAtual);
        nfeCabecalho.setDataEntradaSaida(dataAtual);
        nfeCabecalho.setHoraEntradaSaida(formatoHora.format(dataAtual));
        nfeCabecalho.setBaseCalculoIcms(BigDecimal.ZERO);
        nfeCabecalho.setValorIcms(BigDecimal.ZERO);
        nfeCabecalho.setValorTotalProdutos(BigDecimal.ZERO);
        nfeCabecalho.setBaseCalculoIcmsSt(BigDecimal.ZERO);
        nfeCabecalho.setValorIcmsSt(BigDecimal.ZERO);
        nfeCabecalho.setValorIpi(BigDecimal.ZERO);
        nfeCabecalho.setValorPis(BigDecimal.ZERO);
        nfeCabecalho.setValorCofins(BigDecimal.ZERO);
        nfeCabecalho.setValorFrete(BigDecimal.ZERO);
        nfeCabecalho.setValorSeguro(BigDecimal.ZERO);
        nfeCabecalho.setValorDespesasAcessorias(BigDecimal.ZERO);
        nfeCabecalho.setValorDesconto(BigDecimal.ZERO);
        nfeCabecalho.setValorTotal(BigDecimal.ZERO);

    }

    private void efetuaCalculosDetalhe(List<NfeDetalhe> listaNfeDetalhe, int crt, boolean cupomVinculado, NfeCabecalho nfeCabecalho) {
        NfeDetalhe nfeDetalhe;
        String csosn;
        String cstIcms;
        BigDecimal valorTotalIcms = BigDecimal.ZERO;
        for (int i = 0; i < listaNfeDetalhe.size(); i++) {
            nfeDetalhe = listaNfeDetalhe.get(i);
            // TODO : Como calcular o frete do item?
            nfeDetalhe.setValorFrete(BigDecimal.ZERO);
            // TODO : Como calcular o seguro do item?
            nfeDetalhe.setValorSeguro(BigDecimal.ZERO);
            // TODO : Como calcular o desconto do item?
            nfeDetalhe.setValorDesconto(BigDecimal.ZERO);
            // TODO : Como calcular o valor de outras depesas do item?
            nfeDetalhe.setValorOutrasDespesas(BigDecimal.ZERO);
            // TODO : Deve-se preencher com zero ou um? Porque?
            nfeDetalhe.setEntraTotal('0');
            nfeDetalhe.setOrigemMercadoria('0');
            // TODO : De onde devemos pegar essa informação (nfeDetalhe.setModalidadeBcIcms)?
            nfeDetalhe.setModalidadeBcIcms('3');

            csosn = nfeDetalhe.getCsosn().substring(2, 4);
            cstIcms = nfeDetalhe.getCstIcms().substring(1, 3);

            /*
             * Código Regime Tributário 1 = Simples Nacional 2 = Simples
             * Nacional = excesso de sublimite da receita bruta 3 = Regime
             * Normal
             */

            // TODO : Os cálculos e atribuições abaixo estão corretos?
            if (crt == 1) {//1 = Simples Nacional
                if (cupomVinculado == false) {
                    if (csosn.equals("101")) {  // Tributada pelo Simples Nacional com permissão de crédito
                        nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                        nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                    }

                    if (csosn.equals("102")) {  // Tributada pelo Simples Nacional sem permissão de crédito
                        nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                        nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                        nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    }

                    if (csosn.equals("103")) {  //  Isenção do ICMS no Simples Nacional para faixa de receita bruta
                        nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                        nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                        nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    }

                    if (csosn.equals("201")) { //Tributada pelo Simples Nacional com permissão de crédito e com cobrança do ICMS por substituição tributária
                        nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                        nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                        nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    }

                    if (csosn.equals("202")) { // Tributada pelo Simples Nacional sem permissão de crédito e com cobrança do ICMS por substituição tributária
                        nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                        nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                        nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    }

                    if (csosn.equals("300")) { // 300 - Imune - Classificam-se neste código as operações praticadas por optantes pelo Simples Nacional contempladas com imunidade do ICMS.
                        nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                        nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                        nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    }

                    if (csosn.equals("400")) { // 400 - Não tributada pelo Simples Nacional - Classificam-se neste código as operações praticadas por optantes pelo Simples Nacional não sujeitas à tributação pelo ICMS dentro do Simples Nacional.
                        nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                        nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                        nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    }

                    if (csosn.equals("500")) { //500 - ICMS cobrado anteriormente por substituição tributária (substituído) ou por antecipação - Classificam-se neste código as operações sujeitas exclusivamente ao regime de substituição tributária na condição de substituído tributário ou no caso de antecipações.
                        nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                        nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                        nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    }

                    if (csosn.equals("900")) { //900 - Outros - Classificam-se neste código as demais operações que não se enquadrem nos códigos 101, 102, 103, 201, 202, 203, 300, 400 e 500.
                        nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                        nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                        nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    }

                } //if (cupomVinculado == false) {
                else {
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                }
                nfeDetalhe.setCstIpi("99");
                nfeDetalhe.setBaseCalculoIpi(BigDecimal.ZERO);
                nfeDetalhe.setAliquotaIpi(BigDecimal.ZERO);
                nfeDetalhe.setValorIpi(BigDecimal.ZERO);

                nfeDetalhe.setCstCofins("99");
                nfeDetalhe.setBaseCalculoCofins(BigDecimal.ZERO);
                nfeDetalhe.setValorCofins(BigDecimal.ZERO);
                nfeDetalhe.setAliquotaCofinsReais(BigDecimal.ZERO);

//                nfeDetalhe.setCstPis("99");
                nfeDetalhe.setValorBaseCalculoPis(BigDecimal.ZERO);
                nfeDetalhe.setAliquotaPisReais(BigDecimal.ZERO);
                nfeDetalhe.setValorPis(BigDecimal.ZERO);

            }//if (crt == 1) {//1 = Simples Nacional

            if (crt == 2 || crt == 3) {// 2 = Simples Nacional = excesso de sublimite da receita bruta | 3 - Reginme Normal
                if (cstIcms.equals("00")) { //Tributada integralmente
                    nfeDetalhe.setBaseCalculoIcms(nfeDetalhe.getValorUnitarioComercial());
//                    nfeDetalhe.setAliquotaIcms(nfeDetalhe.getProduto().getTributacaoEstadual().getTaxaIcms());
                    nfeDetalhe.setAliquotaIcms(nfeDetalhe.getProduto().getTaxaIcms());
                    nfeDetalhe.setValorIcms(nfeDetalhe.getAliquotaIcms().divide(BigDecimal.valueOf(100)).multiply(nfeDetalhe.getBaseCalculoIcms()));
                    valorTotalIcms = valorTotalIcms.add(nfeDetalhe.getValorIcms());
                }
                if (cstIcms.equals("10")) {  //Tributada e com cobrança do ICMS por substituição tributária
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
                if (cstIcms.equals("20")) {   //Com redução de base de cálculo
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
                if (cstIcms.equals("30")) {  //Isenta ou não tributada e com cobrança do ICMS por substituição tributária
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
                if (cstIcms.equals("40")) { //40 - Isenta;
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
                if (cstIcms.equals("41")) { //41 - Nao tributada;
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
                if (cstIcms.equals("50")) { //50 Suspensao;
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
                if (cstIcms.equals("51")) { //Diferimento
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
                if (cstIcms.equals("60")) { //ICMS cobrado anteriormente por substituição tributária
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
                if (cstIcms.equals("70")) {  //Com redução da base de cálculo e cobrança do ICMS por substituição tributária
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
                if (cstIcms.equals("90")) {   //Outras
                    nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                    nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                    nfeDetalhe.setValorIcms(BigDecimal.ZERO);
                }
            } else { //if (crt == 2) || crt == 3) {
                nfeDetalhe.setBaseCalculoIcms(BigDecimal.ZERO);
                nfeDetalhe.setAliquotaIcms(BigDecimal.ZERO);
                nfeDetalhe.setValorIcms(BigDecimal.ZERO);
            }

            nfeDetalhe.setCstIpi("99");

            if (nfeDetalhe.getCstIpi().equals("01")
                    || nfeDetalhe.getCstIpi().equals("02")
                    || nfeDetalhe.getCstIpi().equals("03")
                    || nfeDetalhe.getCstIpi().equals("04")
                    || nfeDetalhe.getCstIpi().equals("05")
                    || nfeDetalhe.getCstIpi().equals("51")
                    || nfeDetalhe.getCstIpi().equals("52")
                    || nfeDetalhe.getCstIpi().equals("53")
                    || nfeDetalhe.getCstIpi().equals("54")
                    || nfeDetalhe.getCstIpi().equals("55")) {

                nfeDetalhe.setBaseCalculoIpi(BigDecimal.ZERO);
                nfeDetalhe.setAliquotaIpi(BigDecimal.ZERO);
                nfeDetalhe.setValorIpi(BigDecimal.ZERO);
            }

            if (nfeDetalhe.getCstIpi().equals("00")
                    || nfeDetalhe.getCstIpi().equals("49")
                    || nfeDetalhe.getCstIpi().equals("60")
                    || nfeDetalhe.getCstIpi().equals("99")) {

                nfeDetalhe.setBaseCalculoIpi(BigDecimal.ZERO);
                nfeDetalhe.setAliquotaIpi(BigDecimal.ZERO);
                nfeDetalhe.setValorIpi(BigDecimal.ZERO);
            }

            nfeDetalhe.setCstCofins("99");
            nfeDetalhe.setBaseCalculoCofins(BigDecimal.ZERO);
            nfeDetalhe.setValorCofins(BigDecimal.ZERO);
            nfeDetalhe.setAliquotaCofinsReais(BigDecimal.ZERO);

//            nfeDetalhe.setCstPis("99");
            nfeDetalhe.setValorBaseCalculoPis(BigDecimal.ZERO);
            nfeDetalhe.setAliquotaPisReais(BigDecimal.ZERO);
            nfeDetalhe.setValorPis(BigDecimal.ZERO);

        }//for (int i = 0; i < listaNfeDetalhe.size(); i++) {
        nfeCabecalho.setValorIcms(valorTotalIcms);
    }

    public void enviaNfe(NfeCabecalho nfeCabecalho) {
        try {
            //TODO : com erro 
//            NfeCabecalho nfeCabecalho = (NfeCabecalhoVO) telaNfeDetalhe.getFormDadosNfe().getVOModel().getValueObject();
            Integer IdCliente = nfeCabecalho.getCliente().getId();
            Cliente cliente = JPAUtil.buscarPorId(Cliente.class, IdCliente);
            List<NfeDetalhe> listaNfeDetalhe = nfeCabecalho.getNfeDetalheList();

            //dados da empresa(Emitente)
            Empresa empresa = JPAUtil.buscarPorId(Empresa.class, 1);

            //TODO : pegar dados na tabela de configuracao da NF-e
            NfeConfiguracao nfeConfig = JPAUtil.buscarPorId(NfeConfiguracao.class, 1);
//            SelecionaCertificado selecionaCertificado = new SelecionaCertificado(null, true);
//            selecionaCertificado.setVisible(true);
//            Map map = selecionaCertificado.getDadosCertificado();
//            String caminhoCertificado = (String) map.get("caminhoCertificado");
//            char[] senha = (char[]) map.get("senha");

            //TODO : Convertimento da senha do certificado esta correto??
            String caminhoCertificado = nfeConfig.getCaminhoCertificado() + nfeConfig.getCertificadoDigital();
            char[] senha = (char[]) nfeConfig.getSenhaCertificado().toCharArray();

            GeraXMLEnvio geraXmlNfe = new GeraXMLEnvio();
            String xml = geraXmlNfe.gerarXmlEnvio(nfeCabecalho, empresa, cliente, listaNfeDetalhe, caminhoCertificado, senha);

            EnviaNfe envia = new EnviaNfe();
            Map mapResposta = envia.enviaNfe(xml, caminhoCertificado, senha);

            Boolean autorizado = (Boolean) mapResposta.get("autorizado");
            String resposta = (String) mapResposta.get("resposta");

            if (autorizado) {
                // TODO : Onde salvar os arquivos xml da NF-e?
                // TODO : Pegar dados de onde salvar na tabela de configuração
                String xmlProc = (String) mapResposta.get("xmlProc");
                String caminhoArquivo = nfeConfig.getCaminhoSalvarXml() + nfeCabecalho.getChaveAcesso() + nfeCabecalho.getDigitoChaveAcesso() + "-nfe.xml";
                OutputStream out = new FileOutputStream(new File(caminhoArquivo));
                out.write(xmlProc.getBytes());
                out.close();
                resposta += "\nArquivo salvo em:\n" + caminhoArquivo;
                // TODO : É necessário salvar outros arquivos?
            }
            JSFUtil.addMessageSucesso(resposta);
//            JOptionPane.showMessageDialog(null, resposta, "Aviso do Sistema", JOptionPane.INFORMATION_MESSAGE);
        } catch (Exception e) {
//            List<NfeDetalhe> det = NfeDetalhe.retornaItensDaNfe(nfeCabecalho.getNfeDetalheList().get(0).getIdNfeCabecalho().getId());
//            for (NfeDetalhe d : det) {
//                d.excluir();
//            }
//            nfeCabecalho.excluir();
            JSFUtil.addMessageErro("Erro ao enviar a nfe " + e);
            System.out.println("Erro ao enviar a nfe: " + e);
            e.printStackTrace();
        }
    }
//    public void imprimeDanfe(NfeCabecalho nfeCabecalho) {
//        try {
//            // TODO : O modelo de DANFE utilizado está correto?
////            NfeCabecalho nfeCabecalho = (NfeCabecalhoVO) telaNfeDetalhe.getFormDadosNfe().getVOModel().getValueObject();
//
//            Map map = new HashMap();
//            Image image = new ImageIcon(this.getClass().getResource("/imagens/logo_t2ti.png")).getImage();
//            map.put("Logo", image);
//
//            JRXmlDataSource xml = new JRXmlDataSource("c:\\nfe\\" + nfeCabecalho.getChaveAcesso() + nfeCabecalho.getDigitoChaveAcesso() + "-nfe.xml", "/nfeProc/NFe/infNFe/det");
//            JasperPrint jp = JasperFillManager.fillReport(this.getClass().getResourceAsStream("/com/t2tierp/nfe/danfe/danfeR.jasper"), map, xml);
//            JasperPrintManager.printPage(jp, 0, false);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
}
